package cn.yangliu.springbatch.config;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.job.flow.support.SimpleFlow;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * the type of springbatch
 *
 * <p>
 * .
 *
 * @author 杨柳
 * @date 2021-07-21
 */
@Configuration
public class AsyncBacthConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;


    @Bean
    public Job job2(Flow handleFlow) {
        return jobBuilderFactory.get("user-job-async")
                .incrementer(new RunIdIncrementer())
                .start(handleFlow)
                .build().build();
    }

    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(50);
        threadPoolTaskExecutor.setMaxPoolSize(200);
        threadPoolTaskExecutor.setQueueCapacity(1000);
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        threadPoolTaskExecutor.setAwaitTerminationMillis(60*30);
        threadPoolTaskExecutor.setThreadNamePrefix("data-Job-");
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    @Bean
    public Flow handleFlow(ThreadPoolTaskExecutor threadPoolTaskExecutor,
                           Flow handleUserFlow, Flow handleRoleFlow){
        return new FlowBuilder<SimpleFlow>("handleFlow")
                .split(threadPoolTaskExecutor)
                .add(handleUserFlow, handleRoleFlow)
                .build();
    }

    @Bean
    public Flow handleUserFlow(Step handleUserStep){
        return new FlowBuilder<SimpleFlow>("handleUserFlow")
                .start(handleUserStep)
                .build();
    }

    @Bean
    public Flow handleRoleFlow(Step handleRoleStep){
        return new FlowBuilder<SimpleFlow>("handleRoleFlow")
                .start(handleRoleStep)
                .build();
    }
}
